package io.adrainty.bolee.insurance.repository.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.adrainty.bolee.framework.commons.utils.IdentifierNoUtil;
import io.adrainty.bolee.insurance.models.bo.CategoryBO;
import io.adrainty.bolee.insurance.models.bo.CategoryConditionBO;
import io.adrainty.bolee.insurance.models.bo.CategorySafeguardBO;
import io.adrainty.bolee.insurance.mapper.CategoryCoefficientMapper;
import io.adrainty.bolee.insurance.mapper.CategoryConditionMapper;
import io.adrainty.bolee.insurance.mapper.CategoryMapper;
import io.adrainty.bolee.insurance.mapper.CategorySafeguardMapper;
import io.adrainty.bolee.insurance.models.bo.CategoryCoefficientBO;
import io.adrainty.bolee.insurance.models.entity.CategoryCoefficientEntity;
import io.adrainty.bolee.insurance.models.entity.CategoryConditionEntity;
import io.adrainty.bolee.insurance.models.entity.CategoryEntity;
import io.adrainty.bolee.insurance.models.entity.CategorySafeguardEntity;
import io.adrainty.bolee.insurance.repository.ICategoryRepository;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Set;

/**
 * <p>CategoryServiceRepositoryImpl</p>
 *
 * @author AdRainty
 * @version V1.0.0
 * @description 保险分类管理
 * @since 2025/8/11 10:23:35
 */

@Repository
public class CategoryRepositoryImpl implements ICategoryRepository {

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private CategoryCoefficientMapper categoryCoefficientMapper;

    @Resource
    private CategoryConditionMapper categoryConditionMapper;

    @Resource
    private CategorySafeguardMapper categorySafeguardMapper;

    @Override
    public IPage<CategoryEntity> findCategoryPage(Integer pageNum, Integer pageSize, CategoryEntity searchDTO) {
        Page<CategoryBO> page = new Page<>(pageNum, pageSize);
        Wrapper<CategoryBO> wrapper = getWrapper(searchDTO);
        Page<CategoryBO> selectPage = categoryMapper.selectPage(page, wrapper);
        return selectPage.convert(item -> BeanUtil.toBean(item, CategoryEntity.class));
    }

    @Override
    public List<CategoryEntity> findCategoryList(CategoryEntity searchDTO) {
        Wrapper<CategoryBO> wrapper = getWrapper(searchDTO);
        List<CategoryBO> categoryBOList = categoryMapper.selectList(wrapper);
        return BeanUtil.copyToList(categoryBOList, CategoryEntity.class);
    }

    @Override
    public List<CategoryEntity> findSubCategoryList(String categoryType, String parentCategoryNo) {
        if (StringUtils.isBlank(parentCategoryNo)) return List.of();
        String processNo = IdentifierNoUtil.processNo(parentCategoryNo);
        Wrapper<CategoryBO> wrapper = Wrappers.lambdaQuery(CategoryBO.class)
                .likeRight(CategoryBO::getParentCategoryNo, processNo)
                .eq(StringUtils.isNotBlank(categoryType), CategoryBO::getCategoryType, categoryType)
                .orderByAsc(CategoryBO::getCategoryNo);
        List<CategoryBO> categoryBOList = categoryMapper.selectList(wrapper);
        return BeanUtil.copyToList(categoryBOList, CategoryEntity.class);
    }

    @Override
    public List<CategoryEntity> findSub1LevelCategoryList(String parentCategoryNo) {
        if (StringUtils.isBlank(parentCategoryNo)) return List.of();
        Wrapper<CategoryBO> wrapper = Wrappers.lambdaQuery(CategoryBO.class)
                .eq(CategoryBO::getParentCategoryNo, parentCategoryNo);
        List<CategoryBO> categoryBOList = categoryMapper.selectList(wrapper);
        return BeanUtil.copyToList(categoryBOList, CategoryEntity.class);
    }

    @Override
    public List<CategoryEntity> listCategoryList(List<String> idList) {
        if (CollUtil.isEmpty(idList)) return List.of();
        List<CategoryBO> categoryBOList = categoryMapper.selectBatchIds(idList);
        return BeanUtil.copyToList(categoryBOList, CategoryEntity.class);
    }

    @Override
    public boolean createCategory(CategoryEntity entity) {
        CategoryBO categoryBO = BeanUtil.toBean(entity, CategoryBO.class);
        boolean result = categoryMapper.insert(categoryBO) > 0;
        if (!result) return false;
        BeanUtil.copyProperties(categoryBO, entity);
        return true;
    }

    @Override
    public boolean updateCategory(CategoryEntity entity) {
        CategoryBO categoryBO = BeanUtil.toBean(entity, CategoryBO.class);
        return categoryMapper.updateById(categoryBO) > 0;
    }

    @Override
    public boolean deleteCategory(List<String> deleteIdList) {
        return categoryMapper.deleteByIds(deleteIdList) > 0;
    }

    @Override
    public List<CategoryConditionEntity> findCategoryConditionByCategoryNo(Set<String> categoryNoSet) {
        Wrapper<CategoryConditionBO> wrapper = Wrappers.lambdaQuery(CategoryConditionBO.class)
                .in(CategoryConditionBO::getCategoryNo, categoryNoSet)
                .orderByAsc(CategoryConditionBO::getSortNo)
                .orderByDesc(CategoryConditionBO::getCreatedTime);
        List<CategoryConditionBO> selectList = categoryConditionMapper.selectList(wrapper);
        return BeanUtil.copyToList(selectList, CategoryConditionEntity.class);
    }

    @Override
    public List<CategorySafeguardEntity> findCategorySafeguardByCategoryNo(Set<String> categoryNoSet) {
        Wrapper<CategorySafeguardBO> wrapper = Wrappers.lambdaQuery(CategorySafeguardBO.class)
                .in(CategorySafeguardBO::getCategoryNo, categoryNoSet)
                .orderByAsc(CategorySafeguardBO::getSortNo)
                .orderByDesc(CategorySafeguardBO::getCreatedTime);
        List<CategorySafeguardBO> selectList = categorySafeguardMapper.selectList(wrapper);
        return BeanUtil.copyToList(selectList, CategorySafeguardEntity.class);
    }

    @Override
    public List<CategoryCoefficientEntity> findCategoryCoefficientByCategoryNo(Set<String> categoryNoSet) {
        Wrapper<CategoryCoefficientBO> wrapper = Wrappers.lambdaQuery(CategoryCoefficientBO.class)
                .in(CategoryCoefficientBO::getCategoryNo, categoryNoSet)
                .orderByAsc(CategoryCoefficientBO::getSortNo)
                .orderByDesc(CategoryCoefficientBO::getCreatedTime);
        List<CategoryCoefficientBO> selectList = categoryCoefficientMapper.selectList(wrapper);
        return BeanUtil.copyToList(selectList, CategoryCoefficientEntity.class);
    }

    @Override
    public void deleteCategoryConditionByCategoryNo(List<String> categoryNo) {
        Wrapper<CategoryConditionBO> wrapper = Wrappers.lambdaQuery(CategoryConditionBO.class)
                .in(CategoryConditionBO::getCategoryNo, categoryNo);
        categoryConditionMapper.delete(wrapper);
    }

    @Override
    public void saveBatchCategoryCondition(List<CategoryConditionEntity> conditionVOs) {
        List<CategoryConditionBO> categoryConditionBOList = BeanUtil.copyToList(conditionVOs, CategoryConditionBO.class);
        categoryConditionMapper.insert(categoryConditionBOList);
    }

    @Override
    public void deleteCategoryCoefficientByCategoryNo(List<String> categoryNo) {
        Wrapper<CategoryCoefficientBO> wrapper = Wrappers.lambdaQuery(CategoryCoefficientBO.class)
                .in(CategoryCoefficientBO::getCategoryNo, categoryNo);
        categoryCoefficientMapper.delete(wrapper);
    }

    @Override
    public void saveBatchCategoryCoefficient(List<CategoryCoefficientEntity> coefficientVOs) {
        List<CategoryCoefficientBO> categoryCoefficientBOList = BeanUtil.copyToList(coefficientVOs, CategoryCoefficientBO.class);
        categoryCoefficientMapper.insert(categoryCoefficientBOList);
    }

    @Override
    public void deleteCategorySafeguardByCategoryNo(List<String> categoryNo) {
        Wrapper<CategorySafeguardBO> wrapper = Wrappers.lambdaQuery(CategorySafeguardBO.class)
                .in(CategorySafeguardBO::getCategoryNo, categoryNo);
        categorySafeguardMapper.delete(wrapper);
    }

    @Override
    public void saveBatchCategorySafeguard(List<CategorySafeguardEntity> safeguardVOs) {
        List<CategorySafeguardBO> categorySafeguardBOList = BeanUtil.copyToList(safeguardVOs, CategorySafeguardBO.class);
        categorySafeguardMapper.insert(categorySafeguardBOList);
    }

    @Override
    public List<CategoryConditionEntity> findCategoryConditionList(CategoryConditionEntity entity) {
        Wrapper<CategoryConditionBO> wrapper = getConditionWrapper(entity);
        List<CategoryConditionBO> categoryConditionBOList = categoryConditionMapper.selectList(wrapper);
        return BeanUtil.copyToList(categoryConditionBOList, CategoryConditionEntity.class);
    }

    private static Wrapper<CategoryBO> getWrapper(CategoryEntity searchDTO) {
        return Wrappers.lambdaQuery(CategoryBO.class)
                .eq(StringUtils.isNotBlank(searchDTO.getParentCategoryNo()), CategoryBO::getParentCategoryNo, searchDTO.getParentCategoryNo())
                .eq(StringUtils.isNotBlank(searchDTO.getCategoryNo()), CategoryBO::getCategoryNo, searchDTO.getCategoryNo())
                .eq(StringUtils.isNotBlank(searchDTO.getCategoryName()), CategoryBO::getCategoryName, searchDTO.getCategoryName())
                .eq(StringUtils.isNotBlank(searchDTO.getLeafNode()), CategoryBO::getLeafNode, searchDTO.getLeafNode())
                .eq(StringUtils.isNotBlank(searchDTO.getShowIndex()), CategoryBO::getShowIndex, searchDTO.getShowIndex())
                .eq(StringUtils.isNotBlank(searchDTO.getCategoryType()), CategoryBO::getCategoryType, searchDTO.getCategoryType())
                .eq(StringUtils.isNotBlank(searchDTO.getCheckRule()), CategoryBO::getCheckRule, searchDTO.getCheckRule())
                .eq(searchDTO.getDataState() != null, CategoryBO::getDataState, searchDTO.getDataState())
                .orderByAsc(CategoryBO::getSortNo)
                .orderByDesc(CategoryBO::getCreatedTime);
    }

    private static Wrapper<CategoryConditionBO> getConditionWrapper(CategoryConditionEntity searchDTO) {
        return Wrappers.lambdaQuery(CategoryConditionBO.class)
                .eq(StringUtils.isNotBlank(searchDTO.getCategoryNo()), CategoryConditionBO::getCategoryNo, searchDTO.getCategoryNo())
                .eq(StringUtils.isNotBlank(searchDTO.getConditionKey()), CategoryConditionBO::getConditionKey, searchDTO.getConditionKey())
                .eq(searchDTO.getDataState() != null, CategoryConditionBO::getDataState, searchDTO.getDataState())
                .orderByAsc(CategoryConditionBO::getSortNo)
                .orderByDesc(CategoryConditionBO::getCreatedTime);
    }

}
